class Job < ActiveRecord::Base
  acts_as_ferret :fields => { 
                        :title => {}, 
                        :description => {}, 
                        :skills_description  => {},
                        :commitment_description  => {},
                        :other_requirements => {},
                        :title_for_sort => {:index => :untokenized} 
                        }

  has_many :jobskills
  has_many :skills, :through => :jobskills
  has_many :assignments
  has_many :users, :through => :assignments

  
  translates :title, :description, :skills_description, :commitment_description, :other_requirements, :private_notes
  validates_presence_of :title, :description

  
  # Constants
  JOBS_DISPLAY_PER_PAGE = 20
  
  
  def self.display_list(page)
    paginate :page => page, :per_page => JOBS_DISPLAY_PER_PAGE, :order => "title"
  end
    
  def title_for_sort
    self.title
  end
  
  def assigned?
    !Assignment.find_by_job_id(id).nil?
  end

  def open!
    self.is_open = true
    @opened = true
  end
  
  def recently_opened?
    @opened
  end
  
  def close!
    is_open = false
  end

  def self.find_all_by_skill(skill)
    Jobskill.find_all_by_skill_id(skill.id).map {|jobskill| Job.find_by_id(jobskill.job_id)}    
  end

  def self.find_all_by_user(user)
    Assignment.find_all_by_user_id(user.id).map {|assignment| Job.find_by_id(assignment.job_id)}
  end

  def add_skill(skill_id)
    jobskill = Jobskill.create(:job_id => id, :skill_id => skill_id)
    if jobskill.valid? && jobskill.save!
      return true
    end
    return false
  end

  def remove_skill(skill_id)
    if has_skill(skill_id)
      if Jobskill.delete Jobskill.find_by_job_id_and_skill_id(id, skill_id)
        return true
      end
    end
    return false
  end

  def has_skill(skill_id)
    jobskill = Jobskill.find_by_job_id_and_skill_id(id, skill_id)
    if jobskill.nil?
      return false
    else
      return true
    end
  end

  def get_all_skills
    @jobskills = Jobskill.find_all_by_job_id(id) || []
    @skills = @jobskills.map { |jobskill| Skill.find_by_id(jobskill.skill_id) } || []
  end

  def remove_all_skills
    skills = get_all_skills
    skills.each do |skill|
      remove_skill(skill.id)
    end    
  end

  def add_user(user_id)
    assignment = Assigment.create(:job_id => id, :user_id => user_id)
    if assignment.valid? && assignment.save!
      return true
    end
    return false
  end

  def has_user(user_id)
    assignment = Assignment.find_by_job_id_and_user_id(id, user_id)
    if assignment.nil?
      return false
    end
    return true
  end

  def remove_user(user_id)
    if has_user(user_id)
      if Assignment.delete Assignment.find_by_job_id_and_user_id(id, user_id)
        return true
      end
    end
    return false
  end

  def get_all_users
    assignments = Assignment.find_all_by_job_id(id)
    users = assignments.map {|assignment| User.find_by_id(assignment.user_id) }
  end

  def remove_all_users
    users = get_all_users
    users.each do |user|
      remove_user(user.id)
    end
  end

  # Eligible users are those who:
  # - are active
  # - have all skills the job requires
  def find_eligible_users
    skills_to_match = get_all_skills
    users = Skill.find_skilled(skills_to_match, User)
  end

  protected

  # Delete all assignments and skills belonging to this job before destroying it
  def before_destroy
    remove_all_users
    remove_all_skills
  end
  
end
